package net.ocps.tchs.soap;

import java.util.ArrayList;

import javax.swing.JOptionPane;

import net.ocps.tchs.soap.entity.Entity;
import net.ocps.tchs.soap.entity.Player;
import net.ocps.tchs.soap.event.EventScheduler;
import net.ocps.tchs.soap.event.events.JumpEvent;
import net.ocps.tchs.soap.object.StaticImage;
import net.ocps.tchs.soap.object.StaticObject;
import net.ocps.tchs.soap.worlds.Splash;
import net.ocps.tchs.soap.worlds.TestWorld;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Audio;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.GdxNativesLoader;

public class Main implements ApplicationListener, Runnable {

	public static final int EVENT_FLUSH_MILLIS = 0x96;

	public static World world;
	public static Box2DDebugRenderer debugRenderer; 
	public float musicMod = 0.6f, muMod = 0;

	public Main() {
		GdxNativesLoader.load();
		System.out.println("GAME STARTING, HOLD ONTO YOUR BUTTS");
		world = new World(new Vector2(0, -100), true); 
		/*EventScheduler es =*/ new EventScheduler();
		new Thread( this ).start();

		new Thread(){
			@Override
			public void run() {
				while( true ) {
					try {
						if( !entitys.isEmpty() && !splash ) {
							if( camera.position.x <= entitys.get( 0 ).getX()+entitys.get( 0 ).texture.getWidth()/2 )
								camera.position.add( 0.50f, 0, 0);
							else
								camera.position.add( -0.50f, 0, 0);
							if( camera.position.y <= entitys.get( 0 ).getY()+175) 
								camera.position.add( 0, 0.50f, 0);
							else
								camera.position.add( 0, -0.50f, 0);

							camera.update(true);
							a.setPitch( 0, musicMod+(Math.abs( entitys.get( 0 ).body.getLinearVelocity().x )/60.5f)/6);//(Math.abs( entitys.get( 0 ).body.getLinearVelocity().x )/60.5f)+0.3f );
						}

						if(muMod < 255)
							muMod++;
						else
							muMod = 0;
						Thread.sleep( 2 );
					} catch( Exception e ) {

					}


				}
			}
		}.start();
	}

	@Override
	public void run() {
		while( true ) {		

			try {
				if( Gdx.input.justTouched() ) {
					musicMod+=0.002f;
					if(splashCounter >= 400 && splashCounter < 1250 )
						splashCounter = 1250;
				} 
				if( Gdx.input.isKeyPressed(Keys.ESCAPE) ) {
					map = "map001";
					addStuff();
				}
				if( (entitys.get( 0 ).body.getLinearVelocity().y < 0.3 && entitys.get( 0 ).body.getLinearVelocity().y > -0.3)&& entitys.get( 0 ).jumpCounter > -1 ) {
					entitys.get( 0 ).jumpCounter--;
				}
				if( Gdx.input.isKeyPressed(Keys.SPACE) ) {
					musicMod+=0.002f;
					if(splashCounter >= 400 && splashCounter < 1250 )
						splashCounter = 1250;
					if( entitys.get( 0 ).jumpCounter <= 0 ) {
						entitys.get( 0 ).body.applyForceToCenter( new Vector2( 0, 18000 ) );
						entitys.get( 0 ).jumpCounter = 2;
					}
				}	
				if( Gdx.input.isTouched() && Gdx.input.getY() < (camera.viewportHeight/2)+50 ) {
					musicMod+=0.002f;
					if( entitys.get( 0 ).jumpCounter <= 0 ) {
						entitys.get( 0 ).body.applyForceToCenter( new Vector2( 0, 18000 ) );
						entitys.get( 0 ).jumpCounter = 2;
					}
				}
				if( Gdx.input.isKeyPressed(Keys.D) || Gdx.input.getX() > (camera.viewportWidth/2)+100 && Gdx.input.isTouched() ) {
					if ( ((Player)entitys.get( 0 )).bodyDef.linearVelocity.x < 0 ) {
						((Player)entitys.get( 0 )).bodyDef.linearVelocity.add( Math.abs( ((Player)entitys.get( 1 )).bodyDef.linearVelocity.x ) , 0);
					}
					musicMod+=0.002f;
					entitys.get( 0 ).direction = 1;
					entitys.get( 0 ).setX( 70.5f );
				}
				if( Gdx.input.isKeyPressed(Keys.A) || Gdx.input.getX() < (camera.viewportWidth/2)-100 && Gdx.input.isTouched()) {
					if ( ((Player)entitys.get( 0 )).bodyDef.linearVelocity.x > 0 ) {
						((Player)entitys.get( 0 )).bodyDef.linearVelocity.add( -( ((Player)entitys.get( 1 )).bodyDef.linearVelocity.x ) , 0);
					}
					musicMod+=0.002f;
					entitys.get( 0 ).direction = -1;
					entitys.get( 0 ).setX( -70.5f );
				}


				for( int i = 0; i < entitys.size(); i++ ) {
					for( int ii = 0; ii < entitys.size(); ii++ ) {
						if( Utils.collides( entitys.get( i ).hitbox, entitys.get( ii ).hitbox ) ) {
							if( entitys.get(i).collisionEvent != null && i != ii ) {
								entitys.get(i).collisionEvent.process( entitys.get(i) );
								if( musicMod >= 0.15f )
									musicMod -= 0.05f;
							}
						}
					}
				}

				if(musicMod > 1.2f && entitys.get( 0 ).jumpCounter <= 0 )
					musicMod = 1.1f;
				if(musicMod > 1.5f)
					musicMod = 1.3f;
				if( splashCounter < 1750 ) {
					splashCounter+=2;
					if( splashCounter >= 1250 )
						splasher.batch.setColor(1,1,1,(splashCounter-1000)/4);
				} else
					splash = false;
				if(musicMod > 0.25f) {
					if( entitys.get( 0 ).jumpCounter > 0 )
						musicMod-=0.001f;
					musicMod-=0.001f;
				} 
				if( entitys.get( 0 ).jumpCounter == 1  )
					musicMod+=0.005f;
				if( musicMod < 0.25f )
					musicMod+=0.01f;
				world.step( 1/120f, 24, 24 );  
				//camera.update();
				Thread.sleep( 4-((int)musicMod*2) );
			} catch( Exception e ) {
				//spammer
			}	
		}		
	}			

	@Override	
	public void create() {
		camera = new OrthographicCamera();  
		camera.viewportHeight = 600;  
		camera.viewportWidth = 800;  
		camera.setToOrtho( false, camera.viewportWidth, camera.viewportHeight );
		camera.position.set( camera.viewportWidth * .5f, camera.viewportHeight * .5f, 60f);  

		new Thread(){
			@Override
			public void run() {
				a = Gdx.audio.newSound( Gdx.files.internal("data/sound/main.ogg") );
				a.loop();
				System.out.println("Loaded music into memory");
			}
		}.start();

		addStuff();
		System.out.println("[onCreate] created "+entitys.size()+" entitys and "+staticobjects.size()+" objects");
		camera.position.set( entitys.get( 0 ).getX()+entitys.get( 0 ).texture.getWidth()/2 , entitys.get( 0 ).getY()+175, 0);
		splasher = new StaticImage( 100, 100, 800, 600, "data/soapsplash.gif");
		camera.update();
		//debugRenderer = new Box2DDebugRenderer(); 
	}

	public void addStuff() {
		try {
			entitys.clear();
			staticobjects.clear();
			Utils.loadMap( map );

			for( int i = 0; i < Main.entitys.size(); i++ ) {
				entitys.get( i ).onCreate();
			}
			for( int i = 0; i < Main.staticobjects.size(); i++ ) {
				staticobjects.get( i ).onCreate();
			}
		} catch( Exception e ) {
			e.printStackTrace();
		}
	}

	public void endAll() {
		for( int i = 0; i < entitys.size(); i++ ) {
			entitys.get( i ).batch.end();
		}
		for( int i = 0; i < staticobjects.size(); i++ ) {
			entitys.get( i ).batch.end();
		}
	}

	@Override
	public void dispose() {
		for( int i = 0; i < entitys.size(); i++ ) {
			try {
				entitys.get( i ).batch.dispose();
				entitys.get( i ).texture.getTexture().dispose();
			} catch( Exception e ) {

			}
		}

	}

	/* DONT PUT NONGRAPHICS CODE IN HERE */
	public void render() {
		Gdx.gl.glClearColor((Math.abs( entitys.get( 0 ).body.getLinearVelocity().x )/60.5f), musicMod+(Math.abs( entitys.get( 0 ).body.getLinearVelocity().x )/60.5f)/2, musicMod, musicMod+muMod);
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

		try {
			//debugRenderer.render(world, camera.combined); 
			for( int i = 0; i < entitys.size(); i++ ) {
				entitys.get( i ).render();
			}
			for( int i = 0; i < staticobjects.size(); i++ ) {
				staticobjects.get( i ).render();
			}

			if( splash ) {
				splasher.x = camera.position.x - 400;
				splasher.y = camera.position.y - 300;
				splasher.render();
			}


			Thread.sleep( 16 );
		} catch ( Exception e ) {
			e.printStackTrace();
		}
	}

	@Override
	public void resize(int width, int height) {
	}

	@Override
	public void pause() {
		Gdx.app.exit();
	}

	@Override
	public void resume() {
	}

	public static ArrayList<Entity> entitys = new ArrayList<Entity>();
	public static ArrayList<StaticObject> staticobjects = new ArrayList<StaticObject>();
	public static StaticImage splasher;

	public Sound a;
	public int splashCounter = 0;
	public String map = "run";
	public static String currentMap = "";
	public static boolean splash = true;
	public static long startNano = System.nanoTime();
	public static OrthographicCamera camera;
}
